package com.zb.frame.base.utils;

import com.zb.frame.base.enums.AuthenticationStatus;
import com.zb.frame.base.model.ClaimsResult;
import io.jsonwebtoken.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.xml.bind.DatatypeConverter;
import java.util.Date;
import java.util.UUID;

/**
 * <p>
 *  JWT 生成与解析工具类
 * </p>
 *
 * @author bangZZ
 * @since 2020-06-04
 */
@Component
public class JWTUtil {

    private static final Logger logger = LoggerFactory.getLogger(JWTUtil.class);

    private static String secretKey; // 私钥

    @Value("${zb.config.jwt.secret}")
    public void setSecretKey(String key) {
        secretKey = key;
    }

    private static final String issuer = "bangZZ"; // 签发者
    private static final SignatureAlgorithm type = SignatureAlgorithm.HS256;

    /**
     * 生成一个jwtToken
     * @param subject   所面向的用户：用户Id/用户名/手机号
     * @param expire    有效时间,单位秒s
     * @return json web token
     */
    public static String generatorToken(String subject, Integer expire) {
        JwtBuilder jwt = Jwts.builder();
        // 设置token的唯一标识
        jwt.setId(UUID.randomUUID().toString());
        // 设置token的主体
        jwt.setSubject(subject);
        // 签发者
        jwt.setIssuer(issuer);
        // 签发时间
        jwt.setIssuedAt(new Date());
        // 设置有效时间
        if (null != expire) {
            Date exp = new Date(System.currentTimeMillis() + expire.longValue() * 1000);
            jwt.setExpiration(exp);
        }
        // System.out.println("generatorToken:" + secretKey);
        byte[] secretKeyBytes = DatatypeConverter.parseBase64Binary(secretKey);
        jwt.signWith(type, secretKeyBytes); // 签证
        return jwt.compact();
    }

    /**
     * 解析jwtToken
     * @param token
     * @return
     */
    public static ClaimsResult parseToken(String token) {
        ClaimsResult result = new ClaimsResult();
        // System.out.println("parseToken:" + secretKey);
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(DatatypeConverter.parseBase64Binary(secretKey))
                    .parseClaimsJws(token)
                    .getBody();
            result.setCode(AuthenticationStatus.SUCCESS);
            result.setData(claims);
        } catch (ExpiredJwtException e) {
            result.setCode(AuthenticationStatus.EXPIRED);
        } catch (UnsupportedJwtException e) {
            result.setCode(AuthenticationStatus.UNSUPPORTED);
        } catch (MalformedJwtException e) {
            result.setCode(AuthenticationStatus.MALFORMED);
        } catch (SignatureException e) {
            result.setCode(AuthenticationStatus.SIGNATURE);
        } catch (IllegalArgumentException e) {
            result.setCode(AuthenticationStatus.ILLEGAL);
        }
        return result;
    }
}
